package GUI;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.ImageObserver;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.text.AttributedCharacterIterator;

import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

public class PokerTable
{
    TableFrame frame;
    Controler kontrolerGry;
    VirtualPlayer[] gracze;
    
    PokerTable( Controler kontroler )
    {
        this.kontrolerGry = kontroler;
        //this.faza         = new String("Licytacja wstepna");
        this.gracze       = new VirtualPlayer[kontroler.liczbaGraczy];
        
        
        frame = new TableFrame( this );
        
    }
    

    public void licytacja()
    {
        kontrolerGry.rozpoczecieLicytacji();
    }
    
    public void wymiana()
    {
        kontrolerGry.wymiana();
    }
}




//-----------------------------------------------------------------------
//------------------------------ELEMENTY GUI-----------------------------
//-----------------------------------------------------------------------


class TableFrame extends JFrame
{
    PokerPanel panel;
    MenuPanel  menu;
    
    TableFrame( PokerTable poker )
    {
        super("PokerGame2014");
        
        setBounds             ( 100, 100, 800, 640 );
        addWindowListener     ( new PokerWindowAdapter() );
        setFont               ( new Font( Font.SANS_SERIF, Font.PLAIN, 40 ) );
        setLocationRelativeTo ( null );
        setLayout             ( null );
        panel = new PokerPanel( poker );
        menu  = new MenuPanel ( poker );
        
        panel.setBounds( 0,   0, 600, 640 );
        menu.setBounds ( 600, 0, 200, 640 );
        
        add( panel );
        add( menu ); 
        
        setResizable( false );
    }
}


class PokerPanel extends JPanel
{
    PokerTable poker;
    JLabel[] txtGracze;
    JLabel[] txtKwotaGraczy;
    //JLabel labelTlo;
    Image tlo;
    Image blank;
    Image[] pozostaleKarty;
    JLabel txtAlerts;
    private HandPanel hand;
    
    PokerPanel( PokerTable p )
    {
        setLayout( null );
        
        poker          = p;
        //poker.gracze   = new VirtualPlayer[poker.kontrolerGry.liczbaGraczy];
        txtGracze      = new JLabel[poker.kontrolerGry.liczbaGraczy];
        txtKwotaGraczy = new JLabel[poker.kontrolerGry.liczbaGraczy];
        pozostaleKarty = new Image[3];
        txtAlerts      = new JLabel( "" );
        
        
        for( int i = 0; i < poker.kontrolerGry.liczbaGraczy; i++ )
        {
            txtGracze[i]      = new JLabel("");
            txtGracze[i].setForeground     ( Color.WHITE );
            txtKwotaGraczy[i] = new JLabel("");
            txtKwotaGraczy[i].setForeground( Color.WHITE );
        }
        
        txtAlerts.setForeground   ( Color.WHITE );
        
        Image zakryteKarty = null;
        
        try 
        {
            zakryteKarty = ImageIO.read( new File( "images/blankHand.png" ) );
            blank        = ImageIO.read( new File( "images/blank.png") );
        } catch (IOException e1) 
        {
            txtAlerts.setText("Brak pliku zakrytych kart!");
        }
        
        try
        {
            tlo = ImageIO.read( new File( "images/background.png" ) ); 
        }catch( IOException e2 )
        {
            txtAlerts.setText("Brak pliku tla!");
        }
        
        
        
        //----------------umiejscowienie kontrolek----------------------------
        txtAlerts.setBounds ( 100, 550, 400, 40 );
        
        
        for( int i = 0; i < poker.kontrolerGry.liczbaGraczy; i++ )
        {
            switch(i)
            {
                case 0 :
                {
                    txtGracze[i].setBounds     ( 250, 520, 150, 40 );
                    txtKwotaGraczy[i].setBounds( 250, 540, 100, 40 );
                    break;
                }
                case 1 :
                {
                    txtGracze[i].setBounds     ( 450, 320, 150, 40);
                    txtKwotaGraczy[i].setBounds( 450, 340, 100, 40 );
                    break;
                }
                case 2 :
                {
                    txtGracze[i].setBounds     ( 250, 120, 150, 40);
                    txtKwotaGraczy[i].setBounds( 250, 140, 100, 40 );
                    break;
                }
                case 3 :
                {
                    txtGracze[i].setBounds     ( 50, 320, 150, 40);
                    txtKwotaGraczy[i].setBounds( 50, 340, 100, 40 );
                    break;
                }
                default :
                {
                    System.out.println("WE CAN DO NOTHING");
                }
            }
        }
        
        
        //----------------dodanie kontrolek-----------------------------------
        add( txtAlerts );
        
        for( int i = 0; i < poker.kontrolerGry.liczbaGraczy; i++ )
        {
            add( txtGracze[i] );
            add( txtKwotaGraczy[i] );
        }
    }
    
    public void inicjalizujDlon()
    {
        hand = new HandPanel( poker );
        if( !poker.gracze[poker.kontrolerGry.ktoryGracz-1].player.owner.czyBot() )
        {
            pokazKarty();
        }
        else
        {
            pokazKartyBot();
        }
        
        hand.setBounds      ( 100, 380, 400, 140 );
        add( hand );
    }
    
    public void odblokujDlon()
    {
        hand.czyOdblokowany = true;
    }
    
    public void zablokujDlon()
    {
        hand.czyOdblokowany = false;
    }
    
    public void wyczyscDlon()
    {
        hand.czysc();
    }
    
    public int[] zwrocWymienianeIndeksy()
    {
        return hand.zwrocIndeksy();
    }
    
    public void paintComponent( Graphics g ) 
    {
        poker.kontrolerGry.aktualizacjaGUI();
        g.drawImage( tlo, -10, -10, 650, 650, null );
    }

    public void pokazKarty()
    {   
        hand.pobierzKarty();
        hand.update( hand.getGraphics() );
    }
    
    public void pokazKartyBot()
    {
        hand.pobierzKartyBot();
        hand.update( hand.getGraphics() );
    }
    
}

class LabelKarta extends JLabel
{
    private boolean czyWybrane;
    
    LabelKarta( String tekst )
    {
        super(tekst);
        
        czyWybrane = false;
    }
    
    public boolean zwrocCzyWybrane()
    {
        return czyWybrane;
    }
    
    public void ustawCzyWybrane( boolean wartosc )
    {
        czyWybrane = wartosc;
    }
}

class HandMouseListener implements MouseListener
{
    HandPanel hand;
    LabelKarta karta;
    
    HandMouseListener( HandPanel hand, LabelKarta karta )
    {
        this.hand  = hand;
        this.karta = karta;
    }

    @Override
    public void mouseClicked(MouseEvent e) 
    {
        if( hand.czyOdblokowany )
        {
            karta.ustawCzyWybrane( !karta.zwrocCzyWybrane() );
            hand.paintComponent( hand.getGraphics() );
        }
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }
    
    
}

class HandPanel extends JPanel
{
    Image[] karty;
    LabelKarta[] miejsceNaKarte;
    PokerTable poker;
    boolean czyOdblokowany;         //flaga ustawiona na true tylko jak gra jest w fazie wymiany
    
    HandPanel( PokerTable p )
    {
        setLayout( null );
        
        poker          = p;
        karty          = new Image[5];
        miejsceNaKarte = new LabelKarta[5];
        //setOpaque( false );
        
        for( int i = 0; i < 5; i++ )
        {
            czyOdblokowany    = false;
            miejsceNaKarte[i] = new LabelKarta(""); 
            //karty[i]          = null;
            karty[i]          = poker.gracze[0].zwrocObrazek(i);
            
            miejsceNaKarte[i].setBounds( i*80, 0, 80, 140 );
            //miejsceNaKarte[i].setBorder( BorderFactory.createSoftBevelBorder( BevelBorder.RAISED, Color.DARK_GRAY, Color.LIGHT_GRAY ) );
            
            miejsceNaKarte[i].addMouseListener( new HandMouseListener( this, miejsceNaKarte[i] ) );
            
            add( miejsceNaKarte[i] );
        }
    }
    
    public void pobierzKarty()
    {
        for( int i = 0; i < 5; i++ )
        {
            karty[i] = poker.gracze[poker.kontrolerGry.ktoryGracz-1].zwrocObrazek(i);
        }
    }
    
    public void pobierzKartyBot()
    {
        for( int i = 0; i < 5; i++ )
        {
            karty[i] = poker.frame.panel.blank;
        }
    }
    
    public void czysc()
    {
        for( int i = 0; i < 5; i++ )
        {
            miejsceNaKarte[i].ustawCzyWybrane( false );
        }
        
        paintComponent( this.getGraphics() );
    }
    
    public int[] zwrocIndeksy()
    {
        int[] temp = new int[5];
        int ilosc = 0;
        
        for( int i = 0, j = 0; i < 5; i++ )
        {
            if( miejsceNaKarte[i].zwrocCzyWybrane() )
            {
                ilosc++;
                temp[j] = i;
                j++;
            }
        }
        
        int[] indeksy = new int[ilosc];
        
        for( int i = 0, j = 0; i < ilosc; i++, j++ )
        {
            indeksy[i] = temp[j];
        }
        
        return indeksy;
    }
    
    public void paintComponent( Graphics g ) 
    {
        //poker.frame.panel.paintComponent( poker.frame.panel.getGraphics() );
        g.clearRect( 0, 0, 400, 140);
        
        for( int i = 0; i < 5; i++ )
        {
            //jesli karta nie jest zaznaczona
            if( !miejsceNaKarte[i].zwrocCzyWybrane() )
            {
                g.drawImage( karty[i], i*80, 20, 80, 120, null );
                
            }
            //jesli karta jest zaznaczona
            else
            {
                g.drawImage( karty[i], i*80, 0, 80, 120, null );
            }
        }
    }
}

class MenuPanel extends JPanel
{
    PokerTable poker;
    JLabel txtTuraInfo;
    JLabel txtTura;
    JLabel txtGracz;
    JLabel txtStawka;
    JButton btnZatwierdz;
    JButton btnZakoncz;
    Image tlo;
    JLabel txtFazaGry;
    
    
    
    MenuPanel( PokerTable p )
    {
        poker = p;
        
        setLayout( null );
        setBorder( BorderFactory.createSoftBevelBorder( BevelBorder.RAISED, Color.DARK_GRAY, Color.LIGHT_GRAY ) );
        
        txtTuraInfo  = new JLabel( "Tura: " );
        txtTura      = new JLabel( "" );
        txtGracz     = new JLabel( "Aktualny gracz: " );
        txtStawka    = new JLabel( "Stawka: 0" );
        txtFazaGry   = new JLabel( "Faza: " );
        btnZatwierdz = new JButton( "Licytuj" );
        btnZakoncz   = new JButton( "Zakoncz" );
        
        txtTuraInfo.setBounds ( 20, 20,  100, 40 );
        txtTura.setBounds     ( 70, 20,  100, 40 );
        txtGracz.setBounds    ( 20, 140, 200, 40 );
        txtStawka.setBounds   ( 20, 300, 200, 40 );
        btnZatwierdz.setBounds( 20, 500, 100, 40 );
        btnZakoncz.setBounds  ( 20, 550, 100, 40 );
        txtFazaGry.setBounds  ( 20, 70,  150, 40 );
        
        txtTuraInfo.setForeground( Color.WHITE );
        txtTura.setForeground    ( Color.WHITE );
        txtGracz.setForeground   ( Color.WHITE );
        txtStawka.setForeground  ( Color.WHITE );
        txtFazaGry.setForeground ( Color.WHITE );
        
        
        btnZakoncz.addActionListener  ( new ActionListener() 
                                        {
                                            @Override
                                            public void actionPerformed(ActionEvent e) 
                                            {
                                                 poker.frame.setVisible( false );
                                                 poker.frame.dispose();
                                            }
                                        }
        );
        
        btnZatwierdz.addActionListener( new ActionListener() 
                                        {
                                            @Override
                                            public void actionPerformed(ActionEvent e) 
                                            {

                                                switch( poker.kontrolerGry.faza )
                                                {
                                                    case "Licytacja wstepna" :
                                                    {
                                                        poker.licytacja();
                                                        break;
                                                    }
                                                    case "Wymiana" :
                                                    {
                                                        poker.wymiana();
                                                        break;
                                                    }
                                                    case "Licytacja koncowa" :
                                                    {
                                                        poker.licytacja();
                                                        break;
                                                    }
                                                    
                                                }
                                            }
                                        }
        );
        
        try
        {
            tlo = ImageIO.read( new File("images/pokerMenuBackground.png") );
        }
        catch( IOException e )
        {
            
        }
        
        add( txtTuraInfo );
        add( txtTura );
        add( txtGracz );
        add( txtStawka );
        add( btnZatwierdz );
        add( btnZakoncz );
        add( txtFazaGry );
    }
    
    /*
    public void odswiez( int indeks )
    {
        txtGracz.setText ( "Aktualny gracz: " + poker.kontrolerGry.gracze[indeks].owner.nazwa );
        txtStawka.setText( "Stawka: " + poker.kontrolerGry.stawka );
        txtTura.setText  ( poker.kontrolerGry.tura + "" );
    }
    */
    public void aktualizujStawke( int stawka )
    {
        txtStawka.setText( Integer.toString( stawka ) );
    }
    

    public void paintComponent( Graphics g ) 
    {
        g.drawImage( tlo, 0, 0, 200, 640, null );
    }
}



class PokerWindowAdapter extends WindowAdapter
{
    @Override
    public void windowClosing(WindowEvent e)
    {
        System.exit(0);
    }
}
